﻿using System.Collections.Generic;
using System.Windows.Media;
using Might.Core.DOM;
using Might.Infrastructure.DOM;
using Might.Infrastructure.ModelicaDOM;
using Might.Modelica.Annotations.Graphics;

namespace Might.Core.AST {
    /// <summary>
    /// Abstract syntax tree (AST) class.
    /// </summary>
    public class Ast {
        // TODO until proper file loading and parsing is ready, add/replace here current tokens with new one
        // based solely on Modelica annotation items

        public class FakeModelicaClass : DomNode, IModelicaClass {
            public string ClassName { get; set; }
            public string QualifiedClassName { get; set; }
            public ModelicaClassType RestrictedType { get; set; }
            public bool Encapsulated { get; set; }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="AST"/> class.
        /// </summary>
        internal static void FillDom(DomRoot dom) {
            FakeModelicaClass root = new FakeModelicaClass
                                     {ClassName = "Root", RestrictedType = ModelicaClassType.Class};

            // define root's icon
            IDomNode anotace = new DomNode();
            root.InsertChild(GroupNames.Annotations, anotace);
            Icon i = new Icon();
            i.Children.Add(
                new GraphicsRectangle {
                    Parent = i,
                    Top = 50,
                    Left = 50,
                    Height = 50,
                    Width = 50,
                    Fill = new SolidColorBrush(Colors.Blue),
                    Stroke = new SolidColorBrush(Colors.Black),
                    Thickness = 2,
                });
            i.Children.Add(
                new GraphicsRectangle {
                    Parent = i,
                    Top = 100,
                    Left = 100,
                    Height = 50,
                    Width = 50,
                    Fill = new SolidColorBrush(Colors.DarkGray),
                    Stroke = new SolidColorBrush(Colors.Black),
                    Thickness = 2,
                });
            i.Children.Add(
                new GraphicsRectangle {
                    Parent = i,
                    Top = 150,
                    Left = 150,
                    Height = 50,
                    Width = 50,
                    Fill = new SolidColorBrush(Colors.Brown),
                    Stroke = new SolidColorBrush(Colors.Black),
                    Thickness = 2,
                });

            anotace.InsertChild(GroupNames.Icons, i);

            // define first root's child
            FakeModelicaClass item = new FakeModelicaClass
                                     {ClassName = "child 1", RestrictedType = ModelicaClassType.Class};
            root.InsertChild(GroupNames.ModelicaClasses, item);
            // and it's icon
            anotace = new DomNode();
            item.InsertChild(GroupNames.Annotations, anotace);

            i = new Icon();
            i.Children.Add(
                new GraphicsEllipse {
                    Parent = i,
                    Top = 50,
                    Left = 50,
                    Height = 50,
                    Width = 50,
                    Fill = new SolidColorBrush(Colors.Purple),
                    Stroke = new SolidColorBrush(Colors.Black),
                    Thickness = 2,
                });
            i.Children.Add(
                new GraphicsEllipse {
                    Parent = i,
                    Top = 100,
                    Left = 100,
                    Height = 50,
                    Width = 50,
                    Fill = new SolidColorBrush(Colors.Yellow),
                    Stroke = new SolidColorBrush(Colors.Black),
                    Thickness = 2,
                });
            i.Children.Add(
                new GraphicsEllipse {
                    Parent = i,
                    Top = 150,
                    Left = 150,
                    Height = 50,
                    Width = 50,
                    Fill = new SolidColorBrush(Colors.Orange),
                    Stroke = new SolidColorBrush(Colors.Black),
                    Thickness = 2,
                });

            anotace.InsertChild(GroupNames.Icons, i);

            // define second root's child
            var item2 = new FakeModelicaClass {ClassName = "child 2", RestrictedType = ModelicaClassType.Class};
            item2.InsertReference("icanhazcheesburger:)", new DomReference(item2) {Reference = item});
            root.InsertChild(GroupNames.ModelicaClasses, item2);
            // and it's icon
            anotace = new DomNode();
            item2.InsertChild(GroupNames.Annotations, anotace);

            i = new Icon();
            i.Children.Add(
                new GraphicsEllipse {
                    Parent = i,
                    Top = 150,
                    Left = 50,
                    Height = 50,
                    Width = 50,
                    Fill = new SolidColorBrush(Colors.Red),
                    Stroke = new SolidColorBrush(Colors.Black),
                    Thickness = 2,
                });

            anotace.InsertChild(GroupNames.Icons, i);

            // define third root's child
            item = new FakeModelicaClass {ClassName = "child 3", RestrictedType = ModelicaClassType.Class};
            root.InsertChild(GroupNames.ModelicaClasses, item);

            // and it's icon
            anotace = new DomNode();
            item.InsertChild(GroupNames.Annotations, anotace);

            List<GraphicsPoint> pc = new List<GraphicsPoint> {
                new GraphicsPoint(0, 0),
                new GraphicsPoint(15, 100),
                new GraphicsPoint(30, 10),
                new GraphicsPoint(45, 90),
                new GraphicsPoint(60, 20),
                new GraphicsPoint(75, 80),
                new GraphicsPoint(90, 30),
                new GraphicsPoint(105, 70),
                new GraphicsPoint(120, 40),
                new GraphicsPoint(135, 60),
                new GraphicsPoint(150, 50)
            };

            i = new Icon();
            i.Children.Add(
                new GraphicsLine {
                    Parent = i,
                    Top = 25,
                    Left = 5,
                    Height = 100,
                    Width = 150,
                    Stroke = new SolidColorBrush(Colors.Green),
                    Thickness = 5,
                    points = pc
                });

            anotace.InsertChild(GroupNames.Icons, i);

            // define fourth root's child
            item = new FakeModelicaClass {ClassName = "child 4", RestrictedType = ModelicaClassType.Class};
            root.InsertChild(GroupNames.ModelicaClasses, item);
            // and it's icon
            anotace = new DomNode();
            item.InsertChild(GroupNames.Annotations, anotace);

            List<GraphicsPoint> pc2 = new List<GraphicsPoint> {
                new GraphicsPoint(0, 0),
                new GraphicsPoint(15, 100),
                new GraphicsPoint(30, 10),
                new GraphicsPoint(45, 90),
                new GraphicsPoint(60, 20),
                new GraphicsPoint(75, 80),
                new GraphicsPoint(90, 30),
                new GraphicsPoint(105, 70),
                new GraphicsPoint(120, 40),
                new GraphicsPoint(135, 60),
                new GraphicsPoint(150, 50)
            };

            i = new Icon();
            i.Children.Add(
                new GraphicsPolygon {
                    Parent = i,
                    Top = 25,
                    Left = 5,
                    Height = 100,
                    Width = 150,
                    Fill = new SolidColorBrush(Colors.Red),
                    Stroke = new SolidColorBrush(Colors.Magenta),
                    Thickness = 5,
                    points = pc2
                });
            anotace.InsertChild(GroupNames.Icons, i);

            dom.InsertChild(GroupNames.ModelicaClasses, root);
        }
    }
}